package com.wenx.aqs;

import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.AbstractQueuedSynchronizer;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;

/**
 * 自定义类似ReenTrantLock锁
 */
public class SelfLock implements Lock {

    //state 表示获取锁的状态 1 获取到了锁 0 表示这个锁没有被当前线程拿到
    private static class Sync extends AbstractQueuedSynchronizer {

        @Override
        protected boolean isHeldExclusively() {
            //这里要设置独占锁
            return getState()==1;
        }

        @Override
        protected boolean tryAcquire(int arg) {
            //获取锁
            //state == 0 获取到了锁，更新state = 1
            if (compareAndSetState(0, 1)) {
                //持有锁的线程为当前线程
                setExclusiveOwnerThread(Thread.currentThread());
                return true;
            }
            //返回获取锁的状态
            return false;
        }

        @Override
        protected boolean tryRelease(int arg) {
            //释放锁
            if (getState() == 0) {
                //锁未被占用，抛出异常
                throw new UnsupportedOperationException();
            }
            setExclusiveOwnerThread(null);
            //独占锁，只有一个线程持有锁，不需要使用原子操作
            setState(0);
            return true;
        }

        Condition newCondition() {
            return new ConditionObject();
        }

    }


    private final Sync sync = new Sync();


    @Override
    public void lock() {
        sync.acquire(1);
    }

    @Override
    public void lockInterruptibly() throws InterruptedException {
        sync.acquireInterruptibly(1);
    }

    @Override
    public boolean tryLock() {
        return sync.tryAcquire(1);
    }

    @Override
    public boolean tryLock(long time, TimeUnit unit) throws InterruptedException {
        return sync.tryAcquireNanos(1,unit.toNanos(time));
    }

    @Override
    public void unlock() {
        sync.release(0);
    }

    @Override
    public Condition newCondition() {
        return sync.newCondition();
    }
}
